package com.scs.application.modules.dept.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.scs.application.consts.GlobalConsts;
import com.scs.application.consts.SerialKeys;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.query.QueryContext;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.*;
import com.scs.application.modules.base.entity.Dept;
import com.scs.application.modules.base.entity.Matr;
import com.scs.application.modules.base.entity.Warehouse;
import com.scs.application.modules.base.mapper.MatrMapper;
import com.scs.application.modules.base.service.WarehouseService;
import com.scs.application.modules.base.util.CommonService;
import com.scs.application.modules.cfg.utils.ParameterUtils;
import com.scs.application.modules.dept.dto.ApplyAutoOnWayDTO;
import com.scs.application.modules.dept.dto.ApplyItemVo;
import com.scs.application.modules.dept.dto.MatrUnitKey;
import com.scs.application.modules.dept.dto.TransferKey;
import com.scs.application.modules.dept.entity.Apply;
import com.scs.application.modules.dept.entity.ApplyAuto;
import com.scs.application.modules.dept.entity.ApplyAutoHistory;
import com.scs.application.modules.dept.entity.ApplyItem;
import com.scs.application.modules.dept.mapper.ApplyAutoMapper;
import com.scs.application.modules.dept.service.ApplyAutoHistoryService;
import com.scs.application.modules.dept.service.ApplyAutoService;
import com.scs.application.modules.dept.service.ApplyItemService;
import com.scs.application.modules.dept.service.ApplyService;
import com.scs.application.modules.wm.dto.PickDTO;
import com.scs.application.modules.wm.dto.StockDTO;
import com.scs.application.modules.wm.dto.StockGroupWarehouseMatrDTO;
import com.scs.application.modules.wm.dto.StockSafetyDTO;
import com.scs.application.modules.wm.entity.*;
import com.scs.application.modules.wm.enums.LockBusType;
import com.scs.application.modules.wm.mapper.*;
import com.scs.application.modules.wm.service.StockLockService;
import com.scs.application.modules.wm.service.TransferDemandService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.scs.application.consts.GlobalConsts.DistTransferSourceType.DEPT_APPLY_AUTO;

/**
 * <p>
 * 服务实现类
 * </p>
 */
@Service
public class ApplyAutoServiceImpl extends BaseServiceImpl<ApplyAutoMapper, ApplyAuto> implements ApplyAutoService {

    @Autowired
    private StockSafetyMapper stockSafetyMapper;

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private TransferMapper transferMapper;

    @Autowired
    private DistMapper distMapper;

    @Autowired
    private DistItemMapper distItemMapper;

    @Autowired
    private MatrMapper matrMapper;

    @Autowired
    private ApplyAutoHistoryService applyAutoHistoryService;

    @Autowired
    private ApplyItemService applyItemService;
    @Autowired
    private ApplyService applyService;

    @Autowired
    private StockLockService stockLockService;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private TransferDemandService transferDemandService;

    @Autowired
    private PickItemMapper pickItemMapper;

    @Override
    public List<ApplyAuto> listApplyAutoPDA(ApplyAuto applyAuto) {

        List<ApplyAuto> list = this.baseMapper.listApplyAutoPDA(applyAuto);
        return list;
    }

    /**
     * 创建自动请领单
     */
    @Override
    public String autoCreateApply() {
        this.remove(Wrappers.<ApplyAuto>query().isNull("gmt_response").eq("ref_table", "SAFE_STOCK"));
        List<StockSafetyDTO> stockSafetyList = stockSafetyMapper.getNeedApplyList(Wrappers.query());
        return createApply(stockSafetyList.stream().filter(safety -> flagAutoApply(safety)).collect(Collectors.toList()));
    }

    /**
     * 是否执行自动请领
     * 如果是每天，自动执行
     * 如果是每月或每年，判断末次执行时间
     *
     * @param stockSafetyDTO
     * @return
     */
    private Boolean flagAutoApply(StockSafetyDTO stockSafetyDTO) {
        if (!stockSafetyDTO.getFlagAutoJob()) {
            return false;
        }
        if (StringUtils.isEmpty(stockSafetyDTO.getJobPeriod()) || stockSafetyDTO.getLastExecuteTime() == null || GlobalConsts.periodEveryDay.equals(stockSafetyDTO.getJobPeriod())) { //每天的自动执行
            return true;
        } else if (GlobalConsts.periodEveryMonth.equals(stockSafetyDTO.getJobPeriod())) {//每月的
            return stockSafetyDTO.getLastExecuteTime().plusMonths(1).isBefore(LocalDateTime.now());
        } else if (GlobalConsts.periodEveryYear.equals(stockSafetyDTO.getJobPeriod())) {//每月的
            return stockSafetyDTO.getLastExecuteTime().plusYears(1).isBefore(LocalDateTime.now());
        }
        return true;
    }

    /**
     * 创建单个自动请领单
     */
    @Override
    public void createSingleApply(String warehouseId, String matrId) {
        List<StockSafetyDTO> stockSafetyList = stockSafetyMapper.getNeedApplyList(Wrappers.<StockSafetyDTO>query()
                .eq("warehouse_id", warehouseId)
                .eq("matr_id", matrId));
        createApply(stockSafetyList);
    }

    @Override
    public void createMultipleApply(String warehouseId, List<String> matrIds) {
        List<StockSafetyDTO> stockSafetyList = stockSafetyMapper.getNeedApplyList(Wrappers.<StockSafetyDTO>query()
                .eq("warehouse_id", warehouseId)
                .in("matr_id", matrIds));
        createApply(stockSafetyList);
    }

    @Transactional(rollbackFor = Exception.class)
    public String createApply(List<StockSafetyDTO> stockSafetyList) {
        if (stockSafetyList == null || stockSafetyList.size() == 0) {
            return "没有可生成的数据";
        }
        List<Matr> matrList = matrMapper.selectList(
                Wrappers.<Matr>query().in("id", stockSafetyList.stream().map(StockSafetyDTO::getMatrId).collect(Collectors.toList())));
        List<Warehouse> warehouseList = warehouseService.list();

        List<String> warehouseIdList = stockSafetyList.stream().map(StockSafety::getWarehouseId).distinct().collect(Collectors.toList());
        List<String> matrIdList = stockSafetyList.stream().map(StockSafety::getMatrId).distinct().collect(Collectors.toList());
        List<Stock> stockList = stockMapper.selectList(Wrappers.<Stock>query().in("warehouse_id",warehouseIdList).in("matr_id",matrIdList));
        Map<String,Warehouse> mapWarehouse = warehouseService.list(Wrappers.<Warehouse>query().in("id",warehouseIdList)).stream().collect(Collectors.toMap(o -> o.getId(), o -> o, (o1, o2) -> o1));
        if (stockList != null && stockList.size() > 0) {
            stockSafetyList.forEach(item -> {
                double skuQtyDb = stockList.stream().filter(stock -> stock.getWarehouseId().equals(item.getWarehouseId()) && stock.getMatrId().equals(item.getMatrId())).mapToDouble(Stock::getSkuQty).sum();
                item.setSkuQtyDb(skuQtyDb);
            });
        }


        List<ApplyAuto> applyAutoList = stockSafetyList.stream().map(item -> {
            ApplyAuto applyAuto = new ApplyAuto();
            BeanUtils.copyProperties(item, applyAuto);
            Optional<Warehouse> optWarehouse = warehouseList.stream().filter(wh -> wh.getId().equals(applyAuto.getWarehouseId())).findFirst();
            Optional<Matr> optMatr = matrList.stream().filter(m -> m.getId().equals(applyAuto.getMatrId())).findFirst();
            if (!optWarehouse.isPresent() || !optMatr.isPresent()) { //不存在仓库或者耗材，不自动请领
                applyAuto.setId("-1");
                return applyAuto;
            }
            Warehouse warehouse = optWarehouse.get();
            Matr matr = optMatr.get();
//            非库房备货 和中心库房的安全库存 走采购需求开单 否则 都走配送调拨菜单
            if (warehouse.getFlagCenter() || !matr.getFlagCenterPurchase()){
                applyAuto.setRefType(GlobalConsts.APPLYAUTO_REFTYPE_AUTO_PURCHASE);
            }else {
                applyAuto.setRefType(GlobalConsts.APPLYAUTO_REFTYPE_AUTO_APPLY);
            }
            applyAuto.setSkuQtyStock(item.getSkuQty())
                    .setApplyWarehouseId(warehouse.getId())
                    .setApplyWarehouseName(warehouse.getName())
                    .setWarehouseId(warehouse.getApplyWarehouseId())
                    .setWarehouseName(warehouse.getApplyWarehouseName())
                    .setGmtUpdate(LocalDateTime.now())
                    .setFlagGys(matr.getFlagGys())
                    .setApplyUser("自动")
                    .setSkuPrice(matr.getSkuPrice())
//                    安全库存都是用户结算
                    .setSettlementType(GlobalConsts.SettlementType.usedSettlement)
                    .setRefTable(GlobalConsts.AUTO_REF_TABLE_SAFE)
                    .setFlagOmoc(matr.getFlagOmoc());

            // 单品数量小于安全库存
            if (item.getSkuQty() < item.getSkuQtySafety()) {
                applyAuto.setSkuQtyApply(item.getSkuQtyPerfect() - item.getSkuQty());
                applyAuto.setSkuQtyApply0(item.getSkuQtyPerfect() - item.getSkuQty());
                applyAuto.setDemandPackageQty(Math.ceil(applyAuto.getSkuQtyApply()/applyAuto.getRequiredRate()));
                applyAuto.setDemandPackageQty0(Math.ceil(applyAuto.getSkuQtyApply()/applyAuto.getRequiredRate()));
            } else {
                applyAuto.setSkuQtyApply(0d);
                applyAuto.setSkuQtyApply0(0d);
                applyAuto.setDemandPackageQty(0d);
                applyAuto.setDemandPackageQty0(0d);
            }
            applyAuto.setSkuQtyApply(applyAuto.getSkuQtyApply())
                    .setOnWayQty(0d);

            // 采购需求
            if (applyAuto.getRefType().equals(GlobalConsts.APPLYAUTO_REFTYPE_AUTO_PURCHASE)){
                applyAuto.setBillPackageUnit(applyAuto.getRequiredUnit());
                applyAuto.setBillPackageRate(applyAuto.getRequiredRate());
                applyAuto.setBillPackageQty((item.getSkuQtyPerfect()-item.getSkuQtyDb())/item.getRequiredRate());
            }
            if (StringUtils.isBlank(item.getAutoApplyId())) { //新数据
                applyAuto.setGmtApply(LocalDateTime.now())
                        .setId(null);
            } else {
                applyAuto.setId(item.getAutoApplyId());
            }
            return applyAuto;
        }).collect(Collectors.toList());
        applyAutoList = applyAutoList.stream().filter(auto -> !"-1".equalsIgnoreCase(auto.getId())).collect(Collectors.toList());

        // 排除需采购数量为0的
        applyAutoList = applyAutoList.stream().filter(auto -> auto.getSkuQtyApply() != 0).collect(Collectors.toList());


        if (applyAutoList.size() == 0) {
            return "没有可生成的数据";
        }
        //获取在途订单信息
        List<ApplyAutoOnWayDTO> applyAutoOnWayDTOS = baseMapper.listApplyAutoOnWay(Wrappers.query());

        if (applyAutoOnWayDTOS != null && applyAutoOnWayDTOS.size() > 0) {
            applyAutoList.stream().filter(applyAuto -> StringUtils.isNotEmpty(applyAuto.getRefOrderId())).forEach(applyAuto -> {
                applyAutoOnWayDTOS.stream().filter(onWay -> applyAuto.getId().equals(onWay.getApplyAutoId())).findAny().ifPresent(onWay -> {
                    applyAuto.setOnWayQty(onWay.getOnWayQty());
                    applyAuto.setDemandPackageQty(Math.ceil(applyAuto.getSkuQtyApply() / applyAuto.getRequiredRate()));
                    //如果需求-在途 < 0，订正为0
                    if (applyAuto.getSkuQtyApply() < 0) {
                        applyAuto.setSkuQtyApply(0d);
                        applyAuto.setDemandPackageQty(0d);
                    }
                });
            });
        }
        super.saveOrUpdateBatch(applyAutoList, 500);
        long numDist = applyAutoList.stream().filter(auto -> auto.getRefType().equals(GlobalConsts.APPLYAUTO_REFTYPE_AUTO_APPLY)).count();
        return StrUtil.format("生成结束，需求记录{}，采购记录{}",numDist,applyAutoList.size() - numDist);
    }


    /**
     *
     * 自动更新自动请领表中库存情况和拣货情况
     */
//    @Override
//    public void autoStockPick() {
//        List<ApplyAuto> applyAutoList = this.list();
//        List<ApplyAuto> updateList = new ArrayList<>();
//
//        List<String> msgArr = new ArrayList<>();
//        if (applyAutoList != null && applyAutoList.size() > 0) {
//            List<String> matrIdList = applyAutoList.stream().map(ApplyAuto::getMatrId).distinct().collect(Collectors.toList());
//            List<String> warehouseIdList = applyAutoList.stream().map(ApplyAuto::getWarehouseId).distinct().collect(Collectors.toList());
//            List<String> applyItemList = applyAutoList.stream().map(ApplyAuto::getRefApplyItemId).distinct().collect(Collectors.toList());
//            Map<ApplyStockKey, List<ApplyAuto>> applyAutoMap = applyAutoList.stream().collect(
//                    Collectors.groupingBy(o -> new ApplyStockKey(o.getWarehouseId(), o.getMatrId())));
//            QueryWrapper queryWrapper = Wrappers.<Stock>query().in("matr_id", matrIdList).in("warehouse_id", warehouseIdList);
//            List<StockGroupWarehouseMatrDTO> stockGroupWarehouseMatrDTOS = stockMapper.getListGroupByMatr(queryWrapper, null);
//            if (stockGroupWarehouseMatrDTOS != null && stockGroupWarehouseMatrDTOS.size() > 0) {
//                Map<ApplyStockKey, List<StockGroupWarehouseMatrDTO>> stockKeyListMap = stockGroupWarehouseMatrDTOS.stream().collect(
//                        Collectors.groupingBy(o -> new ApplyStockKey(o.getWarehouseId(), o.getMatrId())));
//                String stockMsg = "无库存";
//                double skuStockQty = 0D;
//                int count = 0;
//                for (ApplyStockKey applyStockKey : applyAutoMap.keySet()) {
//                    List<StockGroupWarehouseMatrDTO> stockGroupList = stockKeyListMap.get(applyStockKey);
//                    List<ApplyAuto> autoList = applyAutoMap.get(applyStockKey);
//                    if (stockGroupList != null && stockGroupList.size() > 0) {
//                        msgArr.clear();
//                        for (StockGroupWarehouseMatrDTO stockGroupWarehouseMatrDTO : stockGroupList) {
//                            msgArr.add(UtilNum.trimZero(stockGroupWarehouseMatrDTO.getPackageQtyUse()) + stockGroupWarehouseMatrDTO.getPackageUnit());
//                            skuStockQty += stockGroupWarehouseMatrDTO.getSkuQtyUse();
//                        }
//                        stockMsg = StringUtils.join(msgArr, "\n");
//                        count += autoList.size();
//                        for (ApplyAuto applyAuto : autoList) {
//                            ApplyAuto applyAutoNew = new ApplyAuto();
//                            applyAutoNew.setStockMsg(stockMsg);
//                            applyAutoNew.setId(applyAuto.getId());
//
//                            updateList.add(applyAutoNew);
//                        }
//                    }
//                }
//                this.updateBatchById(updateList);
//            }
//            List<PickItemGroupByApplyPackageUnitDTO> pickItemGroupList = null;
//            if (applyItemList != null && applyItemList.size() > 0) {
//                QueryWrapper queryWrapperPickItem = Wrappers.query().in("matr_id", matrIdList).in("apply_item_id", applyItemList);
//                pickItemGroupList = pickItemMapper.getListGroupByApplyPackageUnit(queryWrapperPickItem);
//            }
          //已拣货包装列表
//            if (pickItemGroupList != null && pickItemGroupList.size() > 0) {
//                String pickMsg = "未拣货";
//                    Map<String, List<PickItemGroupByApplyPackageUnitDTO>> pickApplyListMap = pickItemGroupList.stream()
//                            .filter(item->StringUtils.isNotBlank(item.getApplyItemId()))
//                            .collect(
//                            Collectors.groupingBy(PickItemGroupByApplyPackageUnitDTO::getApplyItemId));
//                    for (String applyItemId : pickApplyListMap.keySet()) {
//                        List<PickItemGroupByApplyPackageUnitDTO> findList = pickApplyListMap.get(applyItemId);
//                        if (findList != null && findList.size() > 0) {
//                            msgArr.clear();
//                            findList.forEach(pickGroupByApplyDTO -> msgArr.add(UtilNum.trimZero(pickGroupByApplyDTO.getPackageQty()) + pickGroupByApplyDTO.getPackageUnit()));
//                            pickMsg =  StringUtils.join(msgArr, "\n");
//                        }
//                        this.update(Wrappers.<ApplyAuto>update().eq("ref_apply_item_id", applyItemId)
//                                .set("pick_msg", pickMsg));
//                    }
//
//            }
//        }
//
//    }

    /**
     * 转调拨单
     *
     * @param applyAutos
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<Transfer> toTransfer(List<ApplyAuto> applyAutos) {
        //先过滤一下作废的数据和ref_id null
        applyAutos = this.list(Wrappers.<ApplyAuto>query().in("id", applyAutos.stream().map(ApplyAuto::getId).collect(Collectors.toList()))
                .isNull("ref_id"));

        if (applyAutos == null || applyAutos.size() == 0) {
            throw new BusinessException("该调拨需求已作废或者已响应，不能进行响应操作,请重新刷新界面！");
        }
        List<String> matrIdList = applyAutos.stream().map(ApplyAuto::getMatrId).distinct().collect(Collectors.toList());
        List<String> warehouseIdList = applyAutos.stream().map(ApplyAuto::getWarehouseId).distinct().collect(Collectors.toList());
        QueryWrapper queryWrapper = Wrappers.<Stock>query().in("matr_id", matrIdList).in("warehouse_id", warehouseIdList);
        List<StockGroupWarehouseMatrDTO> stockGroupWarehouseMatrDTOS = stockMapper.getListGroupByMatr(queryWrapper, null);
        if (stockGroupWarehouseMatrDTOS == null || stockGroupWarehouseMatrDTOS.size() < 1) {
            BusinessException.throwValidFail("未找到可用库存，不允许响应");
        }
        Map<TransferKey, List<ApplyAuto>> groupMap = Maps.newHashMap();

        Map<String, String> matrBaseType = matrMapper.selectList(
                Wrappers.<Matr>query().in("id", applyAutos.stream().map(ApplyAuto::getMatrId).collect(Collectors.toList()))
        ).stream().collect(Collectors.toMap(Matr::getId, Matr::getBaseType));


        //1、根据配送仓库/目标科室/试剂组/结算类型分组
        applyAutos.forEach(applyAuto -> {
            if (StringUtils.isEmpty(applyAuto.getBillPackageUnit())) {
                applyAuto.setBillPackageUnit(applyAuto.getRequiredUnit());
            }
            if (applyAuto.getBillPackageQty() == null || applyAuto.getBillPackageQty() == 0L) {
                if (applyAuto.getSkuQtyApply() != null && applyAuto.getRequiredRate() != null && applyAuto.getRequiredRate() != 0L) {
                    applyAuto.setBillPackageQty(applyAuto.getSkuQtyApply() / applyAuto.getRequiredRate());
                }
            }
            if (applyAuto.getBillPackageRate() == null || applyAuto.getBillPackageRate() == 0L) {
                applyAuto.setBillPackageRate(applyAuto.getRequiredRate());
            }

            if (applyAuto.getSkuQtyApply0() == null || applyAuto.getSkuQtyApply0() == 0L) {
                applyAuto.setSkuQtyApply0(applyAuto.getSkuQtyApply());
            }
            if (StringUtils.isBlank(applyAuto.getBillPackageUnit())) {
                BusinessException.throwValidFail(String.format("耗材【%s】品规【%s】开单单位不能为空", applyAuto.getMatrName()));
            }
            if (applyAuto.getBillPackageQty() == 0d) {
                BusinessException.throwValidFail(String.format("耗材【%s】品规【%s】开单数量不能为0", applyAuto.getMatrName(), applyAuto.getMatrSpec()));
            }
            //实时库存包装列表
            List<StockGroupWarehouseMatrDTO> findList = stockGroupWarehouseMatrDTOS.stream()
                    .filter(
                            stockGroupWarehouseMatrDTO ->
                                    applyAuto.getMatrId().equals(stockGroupWarehouseMatrDTO.getMatrId())
                                            && applyAuto.getWarehouseId().equals(stockGroupWarehouseMatrDTO.getWarehouseId())
                                            && applyAuto.getBillPackageUnit().equals(stockGroupWarehouseMatrDTO.getPackageUnit())
                    )
                    .collect(Collectors.toList());
            if (findList == null || findList.size() < 1) {
                BusinessException.throwValidFail("耗材【%s】品规【%s】开单单位【%s】未找到可用库存，不允许响应", applyAuto.getMatrName(), applyAuto.getMatrSpec(), applyAuto.getBillPackageUnit());
            }

            double PackageQtyUseSum = UtilNum.getDouble(findList.stream().mapToDouble(StockGroupWarehouseMatrDTO::getPackageQtyUse).sum());
            if (applyAuto.getBillPackageQty() > PackageQtyUseSum) {
                BusinessException.throwValidFail("耗材【%s】品规【%s】开单单位【%s】开单数量【%s】已超过可用库存【%s】，不允许响应", applyAuto.getMatrName(), applyAuto.getMatrSpec(), applyAuto.getBillPackageUnit(), applyAuto.getBillPackageQty(), PackageQtyUseSum);
            }
            if (applyAuto.getSkuQtyApply0() < applyAuto.getPickedSkuQty()) {
                BusinessException.throwValidFail("最新需求数量小于已拣货数量,请检查");
            }

            TransferKey transferKey = new TransferKey(applyAuto.getDeptId(), applyAuto.getSettlementType(), applyAuto.getWarehouseId(), applyAuto.getReagentTeamId());
            groupMap.computeIfAbsent(transferKey, k -> Lists.newArrayList());
            applyAuto.setMatrBaseType(UtilSpd.getMatrBaseType(matrBaseType.get(applyAuto.getMatrId())));
            groupMap.get(transferKey).add(applyAuto);
        });

        List<Transfer> transferList = new ArrayList<>();
        for (TransferKey transferKey : groupMap.keySet()) {
            //2、按照耗材基础分类分组
            GlobalConsts.MATR_BASE_TYPE_KEYS.forEach(baseType -> {
                List<ApplyAuto> applyAutoList = groupMap.get(transferKey).stream().filter(applyAuto -> applyAuto.getMatrBaseType().equals(baseType)).collect(Collectors.toList());
                if (applyAutoList == null || applyAutoList.size() < 1) { return; }
                Transfer transfer = new Transfer();
                ApplyAuto applyAuto = groupMap.get(transferKey).get(0);
                BeanUtils.copyProperties(applyAuto, transfer);
                transfer.setFromWarehouseId(applyAuto.getWarehouseId()).setTransferType(baseType)
                        .setFromWarehouseName(applyAuto.getWarehouseName())
                        .setToWarehouseId(applyAuto.getApplyWarehouseId())
                        .setToWarehouseName(applyAuto.getApplyWarehouseName())
                        .setDeptIdTo(applyAuto.getDeptId())
                        .setDeptNameTo(applyAuto.getDeptName())
                        .setBusKey(serialRuleAdapter.getSerialRuleService().generateCode(SerialKeys.WM_TRANSFER_BUS_KEY))
                        .setBusDate(Calendar.getInstance().getTime())
                        .setBusUser(UserUtils.currentUser().getName())
                        .setBusUserCode(UserUtils.currentUser().getWorkNo())
                        .setPickDate(new Date())
                        .setPicker(null)
                        .setRemark("由自动请领单转化")
                        .setSourceType(DEPT_APPLY_AUTO)
                        .setId(null);

                transfer.setFlowStatus(GlobalConsts.FLOW_PICKING_VALUE);
                //备注：由XXX请领转换，备注：XXX


                List<String> applyItemIdList = applyAutoList.stream().filter(item -> StringUtils.isNotBlank(item.getRefApplyItemId()))
                        .map(ApplyAuto::getRefApplyItemId).collect(Collectors.toList());

                if (applyItemIdList != null && applyItemIdList.size() > 0) {
                    List<ApplyItem> applyItems = applyItemService.list(new QueryWrapper<ApplyItem>().in("id", applyItemIdList));
                    List<Apply> applys = (List) applyService.listByIds(applyItems.stream().map(ApplyItem::getApplyId).collect(Collectors.toList()));
                    if (applys != null && applys.size() > 0) {
                        String transferRemark = "请领单号(备注)：";
                        for (Apply apply : applys) {
                            transferRemark += String.format("%s(%s),",apply.getBusKey(), StringUtils.defaultString(apply.getRemark(),"无备注"));
                        }

                        //去除最后的逗号
                        transferRemark = transferRemark.substring(0, transferRemark.lastIndexOf(","));

                        //最大长度为100
                        if (UtilCommon.length(transferRemark) > 190) {
                            transferRemark = UtilCommon.getStringPre(transferRemark,190) +"..超出省略";
                        }
                        transfer.setRemark(transferRemark);
                    }

                    //更新请领需求明细响应状态
                    ApplyItemServiceImpl.updateResponseForTransferFlowChange(GlobalConsts.FLOW_PICKING_VALUE,"拣货中", applyItemIdList, transfer);
                }

                transferMapper.insert(transfer);
                transferList.add(transfer);
                List<TransferDemand> transferDemands = new ArrayList<>();
                applyAutoList.forEach(item -> {
                    item.setRefId(transfer.getId())
                            .setGmtResponse(LocalDateTime.now());
                    super.updateCascadeById(item);

                    //把自动请领需求复到新的调拨需求单表wm_transfer_demand
                    TransferDemand transferDemand = new TransferDemand();
                    BeanUtils.copyProperties(item, transferDemand);
                    transferDemand.setPackageQty(item.getDemandPackageQty() == null || item.getDemandPackageQty() == 0L ? item.getBillPackageQty() : item.getDemandPackageQty());
                    transferDemand.setTransferId(item.getRefId())
                            .setApplyAutoId(item.getId())
                            .setPackageRate(item.getSkuQtyApply() / transferDemand.getPackageQty())
                            .setRefDemandTable(item.getRefTable())
                            .setPackageUnit(item.getRequiredUnit())
                            .setSkuQty(item.getSkuQtyApply())
                            .setBillSkuQty(transferDemand.getBillPackageQty()*item.getBillPackageRate())
                            .setBillAmount(transferDemand.getBillSkuQty() * transferDemand.getSkuPrice())
                            .setId(null);
                    transferDemands.add(transferDemand);
                });
                if (!transferDemands.isEmpty()){
                    transferDemandService.saveBatch(transferDemands);
                }
            });
        }
        return transferList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<Dist> toDist(List<ApplyItemVo> applyAutos, String targetStatus) {
        ArrayList<ApplyItemVo> itemVos = new ArrayList<>();

        List<String> matrIdList = applyAutos.stream().map(applyItemVo -> applyItemVo.getMatrId()).distinct().collect(Collectors.toList());
        List<String> warehouseIdList = applyAutos.stream().map(applyItemVo -> applyItemVo.getWarehouseId()).distinct().collect(Collectors.toList());
        QueryWrapper queryWrapper = Wrappers.<Stock>query().in("matr_id", matrIdList).in("warehouse_id", warehouseIdList);
        List<StockGroupWarehouseMatrDTO> stockGroupWarehouseMatrDTOS = stockMapper.getListGroupByMatr(queryWrapper, null);
        if (stockGroupWarehouseMatrDTOS == null || stockGroupWarehouseMatrDTOS.size() < 1)
            throw new BusinessException("未找到可用库存，不允许响应");

        Map<String, String> matrBaseType = matrMapper.selectList(
                Wrappers.<Matr>query().in("id", applyAutos.stream().map(ApplyItemVo::getMatrId).collect(Collectors.toList()))
        ).stream().collect(Collectors.toMap(Matr::getId, Matr::getBaseType));


        for (ApplyItemVo applyAuto : applyAutos) {
            if (StringUtils.isBlank(applyAuto.getBillPackageUnit())) {
                applyAuto.setBillPackageUnit(applyAuto.getRequiredUnit());
            }

            //实时库存包装列表
            List<StockGroupWarehouseMatrDTO> findList = stockGroupWarehouseMatrDTOS.stream()
                    .filter(
                            stockGroupWarehouseMatrDTO ->
                                    applyAuto.getMatrId().equals(stockGroupWarehouseMatrDTO.getMatrId())
                                            && applyAuto.getWarehouseId().equals(stockGroupWarehouseMatrDTO.getWarehouseId())
                                            && applyAuto.getBillPackageUnit().equals(stockGroupWarehouseMatrDTO.getPackageUnit())
                    )
                    .collect(Collectors.toList());
            if (findList == null || findList.size() < 1) {
                throw new BusinessException("耗材【%s】品规【%s】开单单位【%s】未找到可用库存，不允许响应", applyAuto.getMatrName(), applyAuto.getMatrSpec(), applyAuto.getBillPackageUnit());
            }

            double PackageQtyUseSum = UtilNum.getDouble(findList.stream().mapToDouble(ob -> ob.getPackageQtyUse()).sum());
            if (applyAuto.getBillPackageQty() > PackageQtyUseSum) {
                throw new BusinessException("耗材【%s】品规【%s】开单单位【%s】开单数量【%s】已超过可用库存【%s】，不允许响应", applyAuto.getMatrName(), applyAuto.getMatrSpec(), applyAuto.getBillPackageUnit(), applyAuto.getBillPackageQty(), PackageQtyUseSum);
            }

            ApplyItemVo applyItemVo = new ApplyItemVo();
            applyItemVo.setApplyUser(applyAuto.getApplyUser());
            ApplyAuto auto = this.getById(applyAuto.getId());
            if (auto == null) {
                throw new BusinessException("请刷新界面重新选择");
            }

            BeanUtils.copyProperties(auto, applyItemVo);
//            原始
            if (auto.getSkuQtyApply0() <= auto.getPickedSkuQty()) {
                throw new BusinessException("请刷新界面重新选择");
            }
            applyItemVo.setDemandQty(auto.getSkuQtyApply() - auto.getPickedSkuQty());
//            applyItemVo.setDemandQty(auto.getDemandPackageQty()-auto.getPickedPackageQty());
            if (applyItemVo.getPackageRate() == null) {
                applyItemVo.setPackageRate(1D);
            }
            applyItemVo.setMatrBaseType(UtilSpd.getMatrBaseType(matrBaseType.get(applyItemVo.getMatrId())));
            itemVos.add(applyItemVo);
        }


        List<Dist> distList = new ArrayList<Dist>();
        //1、按照配送仓库分组
        itemVos.stream().map(ApplyItemVo::getWarehouseId).distinct().forEach(warehouseId -> {
            //2、按照耗材基础分类分组
            GlobalConsts.MATR_BASE_TYPE_KEYS.forEach(baseType -> {
                distList.addAll(
                        convertApplyToDist(itemVos.stream().filter(applyItemVo -> applyItemVo.getWarehouseId().equals(warehouseId) && applyItemVo.getMatrBaseType().equals(baseType)).collect(Collectors.toList()), targetStatus, baseType)
                );
            });
        });

        return distList;

    }

    @Override
    public void updateApplyInfo(List<String> idList,int type) {
        List<String> reSetList = new ArrayList<>();
        List<String> applyAutoIds = Lists.newArrayList();
        List<ApplyAuto> applyAutoUpdate = new ArrayList<>();
        if (type == 1) {
            List<ApplyAutoOnWayDTO> applyAutoOnWayDTOS = this.baseMapper.listApplyAutoOnWay(Wrappers.<ApplyAutoOnWayDTO>query().in("order_id", idList));
            if (applyAutoOnWayDTOS != null && applyAutoOnWayDTOS.size() > 0) {
                applyAutoOnWayDTOS.forEach(applyAutoOnWayDTO -> {
                    applyAutoIds.add(applyAutoOnWayDTO.getApplyAutoId());
                    ApplyAuto applyAuto = new ApplyAuto();
                    if (applyAutoOnWayDTO.getOnWayQty() > 0) {
                        applyAuto.setOnWayQty(applyAutoOnWayDTO.getOnWayQty())
                                .setGmtPurchase(LocalDateTime.now())
                                .setId(applyAutoOnWayDTO.getApplyAutoId());
                        applyAutoUpdate.add(applyAuto);
                    } else {
                        reSetList.add(applyAutoOnWayDTO.getApplyAutoId());
                    }
                });
            }
        }
        if (type==-1){
            reSetList.addAll(idList);
        }
        if (applyAutoUpdate.size() > 0) {
            this.updateBatchById(applyAutoUpdate);
        }
        if (reSetList.size() > 0) {
            this.baseMapper.reSetApplyAuto(reSetList);
        }
        reCalculateApplyAuto(applyAutoIds);
    }

    //重新计算自动请领数量
    private void reCalculateApplyAuto(List<String> applyAutoIds) {
        if (applyAutoIds.isEmpty()) {
            return;
        }
        List<ApplyAuto> applyAutos = list(Wrappers.<ApplyAuto>query().in("id", applyAutoIds));
        if (applyAutos.isEmpty()) {
            return;
        }
        createMultipleApply(applyAutos.get(0).getApplyWarehouseId(), applyAutos.stream().map(ApplyAuto::getMatrId).distinct().collect(Collectors.toList()));
    }

    @Override
    public void respondClose(List<ApplyAuto> applyAutos, String remark) {
        //自动请领单结束 作废
        if (applyAutos.size() > 0) {
            applyAutos.forEach(item -> {
                item.setRefId("0");
                ApplyAutoHistory applyAutoHistory = new ApplyAutoHistory();
                BeanUtils.copyProperties(item, applyAutoHistory);
                applyAutoHistory.setGmtComplete(LocalDateTime.now()).setStatus("-1"); //废弃
                applyAutoHistoryService.save(applyAutoHistory);
                this.removeById(item);
                if (StringUtils.isNotBlank(item.getRefType()) && item.getRefType().indexOf("AUTO") > -1) {
                    //如果是自动请领产生的
                    this.createSingleApply(item.getApplyWarehouseId(), item.getMatrId());
                }

                //去除虚拟锁
                StockLock stockLock = stockLockService.getVirtualLock(LockBusType.APPLY, item.getRefApplyItemId(), item.getWarehouseId());
                if (stockLock != null) {
                    stockLockService.virtualUnlock(LockBusType.APPLY, item.getRefApplyItemId(), item.getWarehouseId());
                }

                //更新需求明细状态
                CommonService.updateApplyItemStatus(item.getRefApplyItemId(), true, remark);
            });
        }

    }

    @Override
    public List<Dept> autoApplyDeptList(QueryContext context) {

        return this.baseMapper.autoApplyDeptList(context.getWrapper());

    }

    @Override
    public List<Dept> autoTransferDeptList(QueryContext context) {

        return this.baseMapper.autoTransferDeptList(context.getWrapper());

    }

    @Override
    public IPage pageForTransfer(QueryContext context) {
        return this.baseMapper.pageForTransfer(context.getPage(), context.getWrapper(), context.getParams());
    }


    private List<Dist> convertApplyToDist(List<ApplyItemVo> applyAutos, String targetStatus, String baseType) {
        Map<String, List<ApplyItemVo>> groupMap = Maps.newHashMap();
        applyAutos.forEach(applyAuto -> {
            applyAuto.setDeptId(applyAuto.getDeptId());
            applyAuto.setDeptName(applyAuto.getDeptName());
            if (groupMap.get(applyAuto.getDeptId()) == null) {
                groupMap.put(applyAuto.getDeptId(), Lists.newArrayList());
            }
            groupMap.get(applyAuto.getDeptId()).add(applyAuto);
        });

        List<Dist> dists = new ArrayList<>();
        double distAmount = 0.0;
        for (String deptId : groupMap.keySet()) {
            Dist dist = new Dist();
            ApplyItemVo applyItemVo = groupMap.get(deptId).get(0);
            dist.setBusKey(serialRuleAdapter.getSerialRuleService().generateCode(SerialKeys.WM_DIST_KEY))
                    .setBusDate(new Date()).setBusUser(UserUtils.currentUser().getName()).setBusUserCode(UserUtils.currentUser().getWorkNo())
                    .setDeptId(applyItemVo.getDeptId()).setDeptName(applyItemVo.getDeptName())
                    .setWarehouseId(applyItemVo.getWarehouseId()).setWarehouseName(applyItemVo.getWarehouseName())
                    .setAmount(0.0).setDistType(baseType).setSourceType(DEPT_APPLY_AUTO).setApplyUser(applyItemVo.getApplyUser());
            if (StringUtils.isNotBlank(targetStatus) && GlobalConsts.YES_STR.equals(targetStatus)) {
                dist.setStatusPick(GlobalConsts.YES).setPicker(UserUtils.currentUser().getName()).setFlowStatus("picking");
                dist.setPickDate(new Date()).setFlowModified(LocalDateTime.now()).setFlowModifier(UserUtils.currentUser().getName());
            }
            distMapper.insert(dist);
            //配送的备注：由XXX请领转换，备注：XXX
            String distRemark = StringUtils.EMPTY;
            List<String> applyKeys = Lists.newArrayList();
            List<String> applyIds = Lists.newArrayList();
            LocalDateTime localDateTime = null;
            List<ApplyItemVo> applyItemVos = groupMap.get(deptId);
            for (ApplyItemVo applyItem : applyItemVos) {
                Matr matr = matrMapper.selectById(applyItem.getMatrId());
                ApplyAuto refId = this.getById(applyItem.getId());
                if (StringUtils.isNotBlank(refId.getRefId())) {
                    throw new BusinessException("请刷新界面,重新选择配送明细");
                }
                DistItem distItem = new DistItem();
                BeanUtils.copyProperties(applyItem, distItem);
                distItem.setId(null);
                double itemAmount = matr.getSkuPrice() * applyItem.getSkuQtyApply();
                distItem.setDistId(dist.getId())
                        .setMatrId(applyItem.getMatrId())
                        .setMatrName(applyItem.getMatrName())
                        .setMatrSpec(applyItem.getMatrSpec())
                        .setPackageUnit(applyItem.getSkuUnit())
                        .setPackageRate(applyItem.getPackageRate())
                        .setPackageQty(applyItem.getSkuQtyApply())
                        .setSkuUnit(applyItem.getSkuUnit())
                        .setSkuPrice(matr.getSkuPrice())
                        .setBillPackageUnit(applyItem.getBillPackageUnit())
                        .setBillPackageQty(applyItem.getBillPackageQty())
                        .setBillPackageRate(applyItem.getBillPackageRate())
                        .setSkuQty(applyItem.getDemandQty())
                        .setPickedSkuQty(0.0)
                        .setAmount(itemAmount);

                //查询科室请领的包装单位信息
                if (StringUtils.isNotBlank(applyItem.getRefApplyItemId())) {
                    ApplyItem applyItem1 = applyItemService.getById(applyItem.getRefApplyItemId());
                    if (applyItem1 != null) {
                        distItem.setPackageUnit(applyItem1.getPackageUnit())
                                .setPackageRate(applyItem1.getPackageRate())

                                .setPackageQty(UtilNum.getDouble((applyItem.getSkuQtyApply() - applyItem.getPickedSkuQty()) / applyItem1.getPackageRate()))
                                .setApplyId(applyItem1.getApplyId())
                                .setApplyItemId(applyItem1.getId())
                                .setSkuQty(applyItem1.getPackageRate() * applyItem1.getPackageQty());
                        if (StringUtils.isNotBlank(applyItem.getBillPackageUnit())) {
                            distItem.setSkuQty(applyItem.getBillPackageQty() * applyItem.getBillPackageRate());
                        }

//                        applyItemService.update(Wrappers.<ApplyItem>update().eq("id",applyItem1.getId()).set("status_dist",1));
                        if (applyIds.indexOf(applyItem1.getApplyId()) < 0) {
                            Apply apply = applyService.getById(applyItem1.getApplyId());
                            if (apply != null) {
                                if (localDateTime == null) {
                                    localDateTime = apply.getGmtCreate();
                                }
                                applyIds.add(applyItem1.getApplyId());
                                applyKeys.add(apply.getBusKey());
                                distRemark += String.format("[-%s-]由请领%s转换    ", StringUtils.isBlank(apply.getRemark()) ? "" : apply.getRemark(), apply.getBusKey());
                            }
                        }
                    }
                }
                //保存配送明细到内存中供后续拣货操作使用 modify by zcl 21/04/23
                distItemMapper.insert(distItem);
                distAmount += itemAmount;
                //根据配送明细自动计算拣货明细并完成拣货操作
//                是否自动拣货配置化
                if (ParameterUtils.getFlagAutoPick()) {
                    calculatePickItem(dist, distItem);
                }
                this.update((Wrappers.<ApplyAuto>update().set("ref_id", dist.getId()).eq("id", applyItem.getId())));


            }
            dist.setRemark(StringUtils.isNotBlank(distRemark) ? distRemark : "需求转配送");
            dist.setAmount(0D)
                    .setApplyDate(DateUtils.localDateTime2Date(LocalDateTime.now()))
                    .setApplyKey(applyKeys.size() > 0 ? applyKeys.stream().collect(Collectors.joining(";")) : "");
            distMapper.updateById(dist);
            dists.add(dist);
        }


        for (String deptId : groupMap.keySet()) {
            List<ApplyItemVo> applyItemVos = groupMap.get(deptId);
            //更新需求明细状态
            for (ApplyItemVo applyItem : applyItemVos) {
                CommonService.updateApplyItemStatus(applyItem.getRefApplyItemId(), false, null);
            }
        }

        return dists;
    }

    //根据配送信息计算出拣货信息
    private void calculatePickItem(Dist dist, DistItem distItem) {
        if (dist != null && distItem != null) {
            Map<String, Object> paramMap = Maps.newHashMap();
            paramMap.put("warehouseId", dist.getWarehouseId());
            paramMap.put("matrId", distItem.getMatrId());
            paramMap.put("packageUnit", distItem.getPackageUnit());
            paramMap.put("skuQty", distItem.getPackageRate());
            if (StringUtils.equals(ParameterUtils.getDistStockPriority(), "1")) {
                paramMap.put("sortField", "in_time");
            } else {
                paramMap.put("sortField", "exp_date");
            }
            //根据配送信息检索匹配的拣货明细
            List<StockDTO> pickStockList = stockMapper.getStockForPickItem(paramMap);
            if (CollectionUtils.isNotEmpty(pickStockList)) {
                //保存满足库存的sn码信息
                List<PickDTO> pickDTOs = new ArrayList<>();

                pickStockList.stream().filter(stock -> {
                    PickDTO pickDto = new PickDTO();
                    pickDto.setDistId(dist.getId());
                    pickDto.setUniqueCode(stock.getSn());
                    pickDTOs.add(pickDto);
                    return pickDTOs.size() == distItem.getPackageQty().intValue();
                }).findAny();
                //根据配送单保存符合条件的捡货明细
                CommonService.pickBatch(pickDTOs);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Deprecated
    public boolean close(String id, String remark) {
//        根据请领单的id查询对应的未作废的明细
//        List<ApplyItem> applyItems = applyItemService.list(Wrappers.<ApplyItem>query().eq("apply_id",id).eq("is_close", 0));
//        if(applyItems.size() == 0){
//            throw new BusinessException("该单据无可作废的明细");
//        }
////        获取请领明细的id集合
//        List<String> itemIds = applyItems.stream().map(s -> s.getId()).collect(Collectors.toList());
////        通过请领明细的id查询需求池中对应的未响应的明细
//        List<ApplyAuto> applyAutos = this.list(Wrappers.<ApplyAuto>query().in("ref_apply_item_id",itemIds).isNull("ref_id"));
//        if(applyAutos.size() == 0){ //若没有未响应的明细直接跳出不报错
//            return true;
////            throw new BusinessException("该单据无可作废的明细");
//        }
////        与需求池的作废保持一致的逻辑
//        respondClose(applyAutos, remark);
////        更新请领单的作废标识
//        Apply apply = applyService.getById(id);
//        apply.setIsClose(true);
//        applyService.saveOrUpdate(apply);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Deprecated
    public boolean closeItem(String id, String remark) {
//        根据请领明细的id查询对应未作废的明细
        List<ApplyItem> applyItems = applyItemService.list(Wrappers.<ApplyItem>query().eq("id", id).eq("is_close", 0));
        if (applyItems.size() == 0) {
            throw new BusinessException("该明细不可作废");
        }
        List<String> itemIds = applyItems.stream().map(s -> s.getId()).collect(Collectors.toList());
//        通过请领明细的id查询需求池中对应的未响应的明细
        List<ApplyAuto> applyAutos = this.list(Wrappers.<ApplyAuto>query().in("ref_apply_item_id", itemIds).isNull("ref_id"));
        if (applyAutos.size() == 0) {
            throw new BusinessException("该明细不可作废");
        }
//        与需求池的作废保持一致的逻辑
        respondClose(applyAutos, remark);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ApplyAuto> listWithHistory(QueryWrapper<ApplyAuto> wrapper) {
        return baseMapper.listWithHistory(wrapper);
    }

    @Override
    public Double getSumAmount(String startDate, String endDate) {
        return this.baseMapper.getSumAmount(startDate, endDate);
    }

    @Override
    public String fillQty(List<ApplyAuto> applyAutos) {

        List<ApplyAuto> addList = new ArrayList<>(applyAutos.size());

        //先过滤一下作废的数据和ref_id null
        applyAutos = this.list(Wrappers.<ApplyAuto>query().in("id", applyAutos.stream().map(ApplyAuto::getId).collect(Collectors.toList()))
                .isNull("ref_id"));

        if (applyAutos == null || applyAutos.size() == 0) {
            throw new BusinessException("该调拨需求已作废或者已响应，不能进行响应操作,请重新刷新界面！");
        }
//        填充数量的需求开单数量都置为0
        applyAutos.forEach(applyAuto -> {
            //                            只更新对应字段
            ApplyAuto applyAutoNew = new ApplyAuto();
            applyAutoNew.setBillPackageQty(0D);
            applyAutoNew.setId(applyAuto.getId());
            addList.add(applyAutoNew);
        });
        this.updateBatchById(addList);
//        清空
        addList.clear();
//        根据 需求单位/耗材id/配送仓库进行分组
        Map<MatrUnitKey, List<ApplyAuto>> keyListMap = applyAutos.stream()
                .collect(Collectors.groupingBy(o -> new MatrUnitKey(o.getRequiredUnit(), o.getMatrId(),o.getWarehouseId())));
        List<String> matrIds = applyAutos.stream().map(ApplyAuto::getMatrId).distinct().collect(Collectors.toList());
        List<String> warehouseIds = applyAutos.stream().map(ApplyAuto::getWarehouseId).distinct().collect(Collectors.toList());
//        查询响应需求所属的配送仓库的库存
        QueryWrapper query = Wrappers.<Stock>query().in("matr_id", matrIds).in("warehouse_id", warehouseIds);
        List<StockGroupWarehouseMatrDTO> stockGroupWarehouseMatrDTOS = stockMapper.getListGroupByMatr(query, null);
        //        根据 需求单位/耗材id/配送仓库进行分组
        Map<MatrUnitKey, List<StockGroupWarehouseMatrDTO>> stockMap = stockGroupWarehouseMatrDTOS.stream()
                .collect(Collectors.groupingBy(o -> new MatrUnitKey(o.getPackageUnit(), o.getMatrId(),o.getWarehouseId())));
        for (MatrUnitKey matrUnitKey : keyListMap.keySet()) {
            if (stockMap.containsKey(matrUnitKey)) {
                List<StockGroupWarehouseMatrDTO> warehouseMatrDTOS = stockMap.get(matrUnitKey);
                List<ApplyAuto> applyAutos1 = keyListMap.get(matrUnitKey);
                double sumDemand = applyAutos1.stream().mapToDouble(ApplyAuto::getDemandPackageQty).sum();
                if (warehouseMatrDTOS != null && warehouseMatrDTOS.size()> 0) {
                    double sum = warehouseMatrDTOS.stream().mapToDouble(StockGroupWarehouseMatrDTO::getPackageQty).sum();
//                    需求包装汇总<=配送仓库库存包装汇总   填写开单数量
                    if (sumDemand <= sum) {
                        for (ApplyAuto applyAuto : applyAutos1) {
//                            只更新对应字段
                            ApplyAuto applyAutoNew = new ApplyAuto();
                            applyAutoNew.setBillPackageUnit(applyAuto.getRequiredUnit());
                            applyAutoNew.setBillPackageRate(applyAuto.getRequiredRate());
                            applyAutoNew.setBillPackageQty(applyAuto.getDemandPackageQty());
                            applyAutoNew.setId(applyAuto.getId());
                            addList.add(applyAutoNew);
                        }
                    }
                }
            }

        }
        if (!addList.isEmpty()) {
            this.updateBatchById(addList);
        }
        return String.format("本次响应【%s】条明细,开单【%s】条明细,有【%s】条明细需要手工填充开单数量", applyAutos.size(), addList.size(), applyAutos.size() - addList.size());
    }

    @Override
    public boolean saveOrUpdate(ApplyAuto entity) {
        if (StringUtils.isNotBlank(entity.getId()) && StringUtils.isNotBlank(entity.getBillPackageUnit()) && entity.getBillPackageQty() != null) {
            if (!UtilNum.isInt(UtilNum.trimZero(entity.getBillPackageQty()))) {
                throw new BusinessException("开单数量目前不支持小数，请选择其他开单单位或者修改开单数量");
            }
        }

       /* if (StringUtils.isNotBlank(entity.getId()) && StringUtils.isNotBlank(entity.getBillPackageUnit())) {
            QueryWrapper queryWrapper = Wrappers.<Stock>query().eq("matr_id", entity.getMatrId()).eq("warehouse_id",entity.getWarehouseId()).eq("package_unit",entity.getBillPackageUnit());
            List<StockGroupWarehouseMatrDTO> stockGroupWarehouseMatrDTOS= stockMapper.getListGroupByMatr(queryWrapper);
            if (stockGroupWarehouseMatrDTOS == null || stockGroupWarehouseMatrDTOS.size() < 1) {
                throw new BusinessException("该耗材已无库存，不允许开单");
            }
            List<StockGroupWarehouseMatrDTO> stockGroupWarehouseMatrDTOSDind = stockGroupWarehouseMatrDTOS.stream().filter(ob -> ob.getPackageUnit().equals(entity.getBillPackageUnit())).collect(Collectors.toList());

            if (stockGroupWarehouseMatrDTOS == null || stockGroupWarehouseMatrDTOS.size() < 1) {
                throw new BusinessException("该耗材该开单单位没有可用库存，请开单其他单位");
            }

                double PackageQtyUseSum = UtilNum.getDouble(stockGroupWarehouseMatrDTOSDind.stream().mapToDouble(ob -> ob.getPackageQtyUse()).sum());

            if (entity.getBillPackageQty()  > PackageQtyUseSum)
                throw new BusinessException("该耗材该单位开单数量[%s]已超过可用库存[%s]，请重新修改开单单位或者数量",entity.getBillPackageQty(),PackageQtyUseSum);
        }*/

        return super.saveOrUpdate(entity);
    }



    @Override
    public Page<?> page(QueryContext context) {
        Page<Map> page = (Page<Map>) super.page(context);
        if (page.getRecords() != null && page.getRecords().size() > 0) {
            List<String> matrIdList = page.getRecords().stream().map(map -> String.valueOf(map.get("matrId"))).distinct().collect(Collectors.toList());
            List<String> warehouseIdList = page.getRecords().stream().map(map -> String.valueOf(map.get("warehouseId"))).distinct().collect(Collectors.toList());
            QueryWrapper queryWrapper = Wrappers.<Stock>query().in("matr_id", matrIdList).in("warehouse_id", warehouseIdList);

            List<StockGroupWarehouseMatrDTO> stockGroupWarehouseMatrDTOS = stockMapper.getListGroupByMatr(queryWrapper, null);

            List<String> msgArr = new ArrayList<>();
            for (Map map : page.getRecords()) {

                //实时库存包装列表
                if (stockGroupWarehouseMatrDTOS != null && stockGroupWarehouseMatrDTOS.size() > 0) {
                    List<StockGroupWarehouseMatrDTO> findList = stockGroupWarehouseMatrDTOS.stream()
                            .filter(stockGroupWarehouseMatrDTO -> (String.valueOf(map.get("matrId"))).equals(stockGroupWarehouseMatrDTO.getMatrId()) && (String.valueOf(map.get("warehouseId"))).equals(stockGroupWarehouseMatrDTO.getWarehouseId()))
                            .collect(Collectors.toList());
                    if (findList != null && findList.size() > 0) {
                        double skuStockQty = 0D;
                        msgArr.clear();
                        for (StockGroupWarehouseMatrDTO stockGroupWarehouseMatrDTO : findList) {
                            msgArr.add(UtilNum.trimZero(stockGroupWarehouseMatrDTO.getPackageQtyUse()) + stockGroupWarehouseMatrDTO.getPackageUnit());
                            skuStockQty += stockGroupWarehouseMatrDTO.getSkuQtyUse();
                        }
                        map.put("stockMsg", StringUtils.join(msgArr, "\n"));
                        map.put("skuQtyStock", skuStockQty);
                        map.put("stockList", findList);
                        double skuQtyApply = Double.parseDouble(String.valueOf(map.get("skuQtyApply")));
                        if (skuStockQty>=skuQtyApply){
                            map.put("stockStatus", 0);
                        }
                        if (skuStockQty < skuQtyApply){
                            map.put("stockStatus", 1);
                        }
                    } else {
                        map.put("stockMsg", "无库存");
                        map.put("stockStatus", -1);
                    }
                }  else {
                    map.put("stockMsg", "无库存");
                    map.put("stockStatus", -1);
                }
            }
        }
        return page;
    }
}
